package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.HashSet;
import java.util.Set;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private Set<String> function = new HashSet<>();
    private TextView result;
    private List<String> keyList;

    //+-*/=
    static String multiflyKey = "multifly";
    static String divideKey = "divide";
    static String plusKey = "plus";
    static String substractKey = "substract";

    /*用于记录操作符前后两次的值
     * 使用StringBuilder可以方便计算带小数点的数，而且比StringBuffer更加快速，抢占线程。
     */
    private StringBuilder oldValue = null;
    private StringBuilder newValue = null;

    //使用该参数去监听是否点击等号，点击等号后如果用户没有点击操作符，而直接点击数字，这时候就需要刷新oldValue而不是去计算。
    private  boolean isClickDone = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SetUp();
    }

    //使用m_click继承了OnClickListener
    class m_click implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.button16:
                    //有操作需要进行
                    caculate(multiflyKey);
                    break;
                case R.id.button13:
                    caculate(divideKey);
                    break;

                case R.id.button14:
                    caculate(plusKey);
                    break;

                case R.id.button15:
                    caculate(substractKey);
                    break;
                case R.id.button17:
                    done();
                    break;
                case R.id.button0:
                    pressNumberButton(0);
                    break;
                case R.id.button1:
                    pressNumberButton(1);
                    break;
                case R.id.button2:
                    pressNumberButton(2);
                    break;
                case R.id.button3:
                    pressNumberButton(3);
                    break;
                case R.id.button4:
                    pressNumberButton(4);
                    break;
                case R.id.button5:
                    pressNumberButton(5);
                    break;
                case R.id.button6:
                    pressNumberButton(6);
                    break;
                case R.id.button7:
                    pressNumberButton(7);
                    break;
                case R.id.button8:
                    pressNumberButton(8);
                    break;
                case R.id.button9:
                    pressNumberButton(9);
                    break;
                case R.id.button10:
                    clear();
                    break;
                case R.id.button18:{
                    if (oldValue == null) {

                        //第一个数字是空的时候
                        oldValue = new StringBuilder(String.valueOf(0)).append(".");
                        result.setText("0.");
                    } else if (newValue == null && !oldValue.toString().contains(".")) {

                        //第一个数字不是空的时候，第二个数字是空，则后加小数点
                        oldValue.append(".");
                        result.setText(oldValue.toString());
                    }
                    //第二个数字不是空而且不是0不包含小数点的时候往后加小数点
                    if (newValue != null && result.getText().toString() != "0" && !result.getText().toString().contains("."))
                        newValue.append(".");
                }
            }
        }
    }

    public void done() {
        if (oldValue == null)
            return;
        if (newValue == null)
            return;
        if (function.size() == 1) {
            isClickDone = true;
            //判断是否有小数点，有的话以double去计算，没有就以integer
            if (newValue.toString().contains(".") || oldValue.toString().contains(".")){
                Double newvalue = Double.valueOf(newValue.toString());
                Double oldvalue = Double.valueOf(oldValue.toString());
                if (function.contains(multiflyKey))
                {
                    String answer = String.valueOf(oldvalue*newvalue);
                    if (answer.endsWith(".0"))
                        result.setText((answer.substring(0, answer.length()-2)));
                    else
                        result.setText(answer);
                    function.remove(multiflyKey);
                    oldValue = new StringBuilder(result.getText().toString()) ;
                    newValue = null;
                    return;
                }

                if (function.contains(divideKey))
                {
                    if (newvalue == 0 && oldvalue != 0)
                        result.setText("Can't divide a 0");
                    else {
                        String answer = String.valueOf(oldvalue/newvalue);
                        if (answer.endsWith(".0"))
                            result.setText((answer.substring(0,answer.length()-2)));
                        else
                            result.setText(answer);
                        function.remove(divideKey);
                        oldValue = new StringBuilder(result.getText().toString()) ;newValue = null;return;
                    }
                }
                if (function.contains(plusKey))
                {
                    result.setText(String.valueOf(newvalue+oldvalue));
                    function.remove(plusKey);
                    oldValue = new StringBuilder(result.getText().toString()) ;
                    newValue = null;return;
                }
                if (function.contains(substractKey))
                {
                    result.setText(String.valueOf(oldvalue-newvalue));
                    function.remove(substractKey);
                    oldValue = new StringBuilder(result.getText().toString()) ;
                    newValue = null;
                    return;
                }
            } else {
                Integer newvalue = Integer.valueOf(newValue.toString());
                Integer oldvalue = Integer.valueOf(oldValue.toString());
                if (function.contains(multiflyKey)) {
                    String answer = String.valueOf(oldvalue*newvalue);
                    if (answer.endsWith(".0"))
                        result.setText((answer.substring(0, answer.length()-2)));
                    else
                        result.setText(answer);
                    function.remove(multiflyKey);
                    oldValue = new StringBuilder(result.getText().toString()) ;
                    newValue = null;
                    return;}
                if (function.contains(divideKey)) {
                    if (newvalue == 0 && oldvalue != 0) {
                        result.setText("Can't divide a 0");
                    } else {
                        String answer = String.valueOf(oldvalue/newvalue);
                        if (answer.endsWith(".0"))
                            result.setText((answer.substring(0, answer.length()-2)));
                        else
                            result.setText(answer);
                        function.remove(divideKey);
                        oldValue = new StringBuilder(result.getText().toString());
                        newValue = null;
                        return;
                    }
                }
                if (function.contains(plusKey)) {
                    result.setText(String.valueOf(newvalue + oldvalue));
                    function.remove(plusKey);oldValue = new StringBuilder(result.getText().toString());
                    newValue = null;
                    return;
                }
                if (function.contains(substractKey)) {
                    result.setText(String.valueOf(oldvalue - newvalue));
                    function.remove(substractKey);
                    oldValue = new StringBuilder(result.getText().toString());
                    newValue = null;
                    return;
                }
            }
        }
    }

    public void caculate(String key) {

        //oldValue如果为空那么就没有比较去操作计算，比如用户一进来就瞎点+-*/。
        if (oldValue == null)
            return;
        //判断是否为空，为空就直接添加key
        if (function.isEmpty()) {
            function.add(key);
        } else {
            if (newValue == null) {
                function.removeAll(keyList);
                function.add(key);
                return;
            }
            if (oldValue.toString().contains(".") || newValue.toString().contains(".")) {

                Double oldvalue = Double.valueOf(oldValue.toString());

                //newvalue = 等于null的时候证明用户输入了一个数， 然后一直按加减乘除，而没有输入其他数
                Double newvalue = Double.valueOf(newValue.toString());

                if (function.contains(multiflyKey)) {

                    String answer = String.valueOf(oldvalue * newvalue);
                    //注意下面*和/都有这个处理，5*2.0 = 10.0，我们这里把10.0的.0去掉，结果得到整数都可以去掉，美观点。
                    if (answer.endsWith(".0"))
                        result.setText((answer.substring(0, answer.length()-2)));
                    else
                        result.setText(answer);

                    function.remove(multiflyKey);
                    function.add(key);
                    oldValue = new StringBuilder(result.getText().toString());
                    newValue = null;
                    return;
                }

                if (function.contains(divideKey)) {
                    if (newvalue == 0 && oldvalue != 0) {
                        result.setText("Can't divide a 0");
                    } else {
                        String answer = String.valueOf(oldvalue / newvalue);
                        if (answer.endsWith(".0"))
                            result.setText((answer.substring(0, answer.length()-2)));
                        else
                            result.setText(answer);

                        function.remove(divideKey);
                        function.add(key);
                        oldValue = new StringBuilder(result.getText().toString());
                        newValue = null;
                        return;
                    }
                }

                if (function.contains(plusKey)) {
                    function.remove(plusKey);
                    function.add(key);
                    if (newValue == null)
                        return;
                    result.setText(String.valueOf(newvalue + oldvalue));
                    oldValue = new StringBuilder(result.getText().toString());
                    newValue = null;
                    return;
                }

                if (function.contains(substractKey)) {
                    function.remove(substractKey);
                    function.add(key);
                    //这里要放到后面，否则不能记录哪个是最后点击的操作符，如果用户连续点加减乘除
                    if (newValue == null)
                        return;
                    result.setText(String.valueOf(oldvalue - newvalue));
                    oldValue = new StringBuilder(result.getText().toString()) ;
                    newValue = null;
                    return;
                }
            } else {
                //整数，操作跟上面大致一样
                Integer oldvalue = Integer.valueOf(oldValue.toString());

                //newvalue = 等于null的时候证明用户输入了一个数， 然后一直按加减乘除，而没有输入其他数
                Integer newvalue = Integer.valueOf(newValue.toString());

                if (function.contains(multiflyKey)) {
                    String answer = String.valueOf(oldvalue*newvalue);
                    if (answer.endsWith(".0"))
                        result.setText((answer.substring(0, answer.length()-2)));
                    else
                        result.setText(answer);
                    function.remove(multiflyKey);
                    function.add(key);
                    oldValue = new StringBuilder(result.getText().toString());
                    newValue = null;
                    return;
                }
                if (function.contains(divideKey)) {
                    if (newvalue == 0 && oldvalue != 0) {
                        result.setText("Can't divide a 0");
                    } else {
                        String answer = String.valueOf(oldvalue / newvalue);
                        if (answer.endsWith(".0"))
                            result.setText((answer.substring(0, answer.length()-2)));
                        else
                            result.setText(answer);
                        function.remove(divideKey);
                        function.add(key);
                        oldValue = new StringBuilder(result.getText().toString());
                        newValue = null;
                        return;
                    }
                }
                if (function.contains(plusKey)) {
                    function.remove(plusKey);
                    function.add(key);
                    if (newValue == null)
                        return;
                    result.setText(String.valueOf(newvalue + oldvalue));
                    oldValue = new StringBuilder(result.getText().toString());
                    newValue = null;
                    return;
                }
                if (function.contains(substractKey)) {
                    function.remove(substractKey);
                    function.add(key);
                    if (newValue == null)
                        return;
                    result.setText(String.valueOf(oldvalue - newvalue));
                    oldValue = new StringBuilder(result.getText().toString());
                    newValue = null;
                    return;
                }
            }
        }
    }

    ///数字按钮
    public void pressNumberButton(int num) {

        String resStr = result.getText().toString();

        //判断是否有操作
        if (function.isEmpty()) {

            if (resStr.startsWith("0") && !result.getText().toString().contains(".")) {

                //这是判断没小数
                oldValue = new StringBuilder(String.valueOf(num));
                result.setText(String.valueOf(num));
            } else if (result.getText().toString().contains(".")) {

                //判断有小数
                oldValue.append(num);
                result.setText(oldValue.toString());
            } else if (newValue == null && isClickDone == true) {

                //这里处理经过一次等于操作后, 用户直接输入, 取代oldValue
                oldValue = new StringBuilder(String.valueOf(num));
                result.setText(oldValue.toString());
                isClickDone = false;

            } else {

                //正常append
                oldValue.append(num);
                result.setText(oldValue.toString());
            }
        } else {

            if (newValue == null) {
                newValue = new StringBuilder(String.valueOf(num));
                result.setText(newValue.toString());
            } else {
                newValue.append(num);
                result.setText(newValue.toString());
            }
        }
    }

    public void clear() {
        oldValue = null;
        newValue = null;
        function.removeAll(keyList);
        result.setText("0");
    }

    //公有方法
    public void SetUp() {

        Button btn0 = findViewById(R.id.button0);
        btn0.setOnClickListener(new m_click());
        //这里本应该监听OnClickListener，但是为了统一管理自己实现m_click类继承OnClickListener

        Button btn1 = findViewById(R.id.button1);
        btn1.setOnClickListener(new m_click());

        Button btn2 = findViewById(R.id.button2);
        btn2.setOnClickListener(new m_click());

        Button btn3 = findViewById(R.id.button3);
        btn3.setOnClickListener(new m_click());

        Button btn4 = findViewById(R.id.button4);
        btn4.setOnClickListener(new m_click());

        Button btn5 = findViewById(R.id.button5);
        btn5.setOnClickListener(new m_click());

        Button btn6 = findViewById(R.id.button6);
        btn6.setOnClickListener(new m_click());

        Button btn7 = findViewById(R.id.button7);
        btn7.setOnClickListener(new m_click());

        Button btn8 = findViewById(R.id.button8);
        btn8.setOnClickListener(new m_click());

        Button btn9 = findViewById(R.id.button9);
        btn9.setOnClickListener(new m_click());

        Button btn10 = findViewById(R.id.button10);
        btn10.setOnClickListener(new m_click());

        Button btn11 = findViewById(R.id.button11);
        btn11.setOnClickListener(new m_click());

        Button btn12 = findViewById(R.id.button12);
        btn12.setOnClickListener(new m_click());

        Button btn13 = findViewById(R.id.button13);
        btn13.setOnClickListener(new m_click());

        Button btn14 = findViewById(R.id.button14);
        btn14.setOnClickListener(new m_click());

        Button btn15 = findViewById(R.id.button15);
        btn15.setOnClickListener(new m_click());

        Button btn16 = findViewById(R.id.button16);
        btn16.setOnClickListener(new m_click());

        Button btn17 = findViewById(R.id.button17);
        btn17.setOnClickListener(new m_click());

        Button btn18 = findViewById(R.id.button18);
        btn18.setOnClickListener(new m_click());

        result = findViewById(R.id.textView);

        keyList = new ArrayList<>();
        keyList.add(multiflyKey);
        keyList.add(divideKey);
        keyList.add(plusKey);
        keyList.add(substractKey);
    }
}
